home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / comm / net / zombie.lha / zombie.c < prev    next >
Text File  |  1995-06-05  |  9KB  |  438 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <time.h>
  4. #include <ctype.h>
  5.  
  6. #define PFSIZE (22*40)
  7.  
  8. extern unsigned long rand( void );
  9.  
  10. unsigned char playfield[ PFSIZE ] = {
  11. "#####################   Legende:        "
  12. "#.........#.........#   @ - DU          "
  13. "#.........#.........#   L - Lebender    "
  14. "#.........#.........#   Z - Zombie      "
  15. "#.........#.........#   O - Oberzombie  "
  16. "#.........#.........#   T - Treuhänder  "
  17. "#.........#.........#   ################"
  18. "#.........#.........#####..............#"
  19. "########..#...#######..................#"
  20. "#......#..................#########....#"
  21. "#.........###########..........#.......#"
  22. "########..#.........#..........#.......#"
  23. "#.........#.........#..........#.......#"
  24. "########............#..........#.......#"
  25. "#.........#.........#..........#.......#"
  26. "########..###########..........#.......#"
  27. "#......#..#.........####################"
  28. "#...####..#.........#                   "
  29. "#...................#                   "
  30. "#..................##                   "
  31. "#####^###############                   "
  32. };
  33.  
  34. unsigned char pf2[ PFSIZE ];
  35.  
  36. int my_x, my_y;
  37. int oz_x, oz_y, ostate;
  38. int th_x, th_y, tstate;
  39. int p_x[ 10 ], p_y[ 10 ], pstate[ 10 ];
  40. int step, lives, nextmiete;
  41.  
  42. #define PF(x,y) playfield[(y)*40+(x)]
  43.  
  44. #define RND(x) (rand()%(x))
  45.  
  46. //
  47. //    Arg-String-Format (alles Hex)
  48. //  SSSSSSLMXMYOXOYOTXTYT[PXPYP]*10
  49. //  Step
  50. //
  51.  
  52. static void makeparmstring( int mx, int my )
  53. {
  54.     int c;
  55.  
  56.     printf( "%06x%01x", step + 1, lives );
  57.     printf( "%02x%02x", my_x + mx, my_y + my );
  58.     printf( "%02x%02x", oz_x, oz_y );
  59.     printf( "%02x%02x", th_x, th_y );
  60.     printf( "%01x", tstate );
  61.     printf( "%01x", ostate );
  62.  
  63.     for( c = 0; c < 10; c++ )
  64.     {
  65.         printf( "%02x%02x%01x", p_x[ c ], p_y[ c ], pstate[ c ] );
  66.     }
  67. }
  68.  
  69. static void printpf( void )
  70. {
  71.     int x, y;
  72.     int c;
  73.     int zc = 0;
  74.  
  75.     PF(my_x,my_y) = '@';
  76.     PF(oz_x,oz_y) = 'O';
  77.     PF(th_x,th_y) = ( tstate & 1 ) ? 't' : 'T';
  78.  
  79.     for( c = 0; c < 10; c++ )
  80.     {
  81.         PF( p_x[ c ], p_y[ c ] ) = ( pstate[ c ] & 1 ) ? 'Z' : 'L';
  82.         if( pstate[ c ] & 1 )
  83.             zc++;
  84.     }
  85.  
  86.     printf( "Spielzug Nr. <B>%d</B>\n...Mieten: <B>%d</B>...Nächste Miete fällig in <B>%d</B> Zügen", step, lives, nextmiete );
  87.     printf( "<BR>Zombies <B>%d</B>, Lebende <B>%d</B> - Treuhänder ist <B>%s</B>\n",
  88.         zc, 10 - zc, ( tstate & 1 ) ? "verzombt" : "lebend"
  89.     );
  90.     printf( "<PRE>" );
  91.  
  92.     for( y = 0; y < 21; y++ )
  93.     {
  94.         int x;
  95.         for( x = 0; x < 40; x++ )
  96.         {
  97.             int ch = playfield[ y * 40 + x ];
  98.             if( ch == '.' || ch == '#' || ch == ' ' )
  99.                 putchar( ch );
  100.             else
  101.                 printf( "<B>%c</B>", ch );
  102.         }
  103.         printf( "\n" );
  104.     }
  105.     printf( "</PRE>" );
  106.  
  107.     printf( "Mögliche Richtungen: " );
  108.     if( PF(my_x-1,my_y) == '.' )
  109.     {
  110.         printf( "[<A HREF=\"/cgi-bin/zombie?" );
  111.         makeparmstring( -1, 0 );
  112.         printf( "\">LINKS</A>]" );
  113.     }
  114.     if( PF(my_x+1,my_y) == '.' )
  115.     {
  116.         printf( "[<A HREF=\"/cgi-bin/zombie?" );
  117.         makeparmstring( 1, 0 );
  118.         printf( "\">RECHTS</A>]" );
  119.     }
  120.     if( PF(my_x,my_y+1) == '.' )
  121.     {
  122.         printf( "[<A HREF=\"/cgi-bin/zombie?" );
  123.         makeparmstring( 0, 1 );
  124.         printf( "\">RUNTER</A>]" );
  125.     }
  126.     if( PF(my_x,my_y-1) == '.' )
  127.     {
  128.         printf( "[<A HREF=\"/cgi-bin/zombie?" );
  129.         makeparmstring( 0, -1 );
  130.         printf( "\">HOCH</A>]" );
  131.     }
  132.     printf( "[<A HREF=\"/cgi-bin/zombie?" );
  133.     makeparmstring( 0, 0 );
  134.     printf( "\">WARTEN</A>]" );
  135.     printf( "<BR>" );
  136. }
  137.  
  138. static void initgame( void )
  139. {
  140.     int c;
  141.  
  142.     my_x = 4;
  143.     my_y = 3;
  144.     oz_x = 28;
  145.     oz_y = 15;
  146.     th_x = 12;
  147.     th_y = 5;
  148.     tstate = 1;
  149.  
  150.     PF(my_x,my_y) = '@';
  151.     PF(oz_x,oz_y) = 'O';
  152.     PF(th_x,th_y) = ( tstate & 1 ) ? 't' : 'T';
  153.  
  154.     for( c = 0; c < 10; c++ )
  155.     {
  156.         int xp, yp;
  157.         do
  158.         {
  159.             xp = RND(40);
  160.             yp = RND(21);        
  161.         }
  162.         while( PF(xp,yp)!='.' );
  163.         p_x[ c ] = xp;
  164.         p_y[ c ] = yp;
  165.         PF(xp,yp)='!';
  166.  
  167.         if( c > 2 )
  168.             pstate[ c ] |= 1;
  169.     }
  170.  
  171.     step = 1;
  172.     lives = 3;
  173.  
  174.     nextmiete = 29 - ( step % 30 );
  175.  
  176.     printpf();
  177. }
  178.  
  179. static void gethex( char *s, int offs, int len, int *to )
  180. {
  181.     int hv = 0;
  182.  
  183.     s += offs;
  184.  
  185.     while( len-- )
  186.     {
  187.         int dig = 0;
  188.  
  189.         if( isdigit( *s ) )
  190.             dig = *s - '0';
  191.         else if( *s >= 'a' && *s <='f')
  192.             dig = ( *s - 'a' ) + 10;
  193.         else if( *s >= 'A' && *s <='F')
  194.             dig = ( *s - 'a' ) + 10;
  195.  
  196.         hv <<= 4;
  197.         hv += dig;
  198.         s++;
  199.     }
  200.     *to = hv;
  201. }
  202.  
  203. static void parsearg( char *s )
  204. {
  205.     int c;
  206.     gethex( s, 0, 6, &step );
  207.     gethex( s, 6, 1, &lives );
  208.     gethex( s, 7, 2, &my_x );
  209.     gethex( s, 9, 2, &my_y );
  210.     gethex( s, 11, 2, &oz_x );
  211.     gethex( s, 13, 2, &oz_y );
  212.     gethex( s, 15, 2, &th_x );
  213.     gethex( s, 17, 2, &th_y );
  214.     gethex( s, 19, 1, &tstate );
  215.     gethex( s, 20, 1, &ostate );
  216.     for( c = 0; c < 10; c++ )
  217.     {
  218.         gethex( s, 21 + c*5, 2, &p_x[ c ] );
  219.         gethex( s, 23 + c*5, 2, &p_y[ c ] );
  220.         gethex( s, 25 + c*5, 1, &pstate[ c ] );
  221.     }
  222. }
  223.  
  224. static void movep( int *xpp, int *ypp, int *dir )
  225. {
  226.     int xp, yp;
  227.     int e, d;
  228.  
  229.     d = ( ( *dir ) >> 1 ) & 3;
  230.  
  231.     if( RND(25)==12 )
  232.         d = RND(4);
  233.  
  234.     for( e = 0; e < 4; e++, d += RND(35) )
  235.     {
  236.         xp = *xpp;
  237.         yp = *ypp;
  238.         switch( d % 4 )
  239.         {
  240.             case 0:
  241.                 xp--;
  242.                 break;
  243.  
  244.             case 1:
  245.                 xp++;
  246.                 break;
  247.  
  248.             case 2:
  249.                 yp--;
  250.                 break;
  251.  
  252.             case 3:
  253.                 yp++;
  254.                 break;
  255.         }
  256.  
  257.         if( PF(xp,yp)=='.')
  258.             break;
  259.     }
  260.     if( e < 4 )
  261.     {
  262.         *xpp = xp;
  263.         *ypp = yp;
  264.         *dir &= ~(3<<1);
  265.         *dir |= (d%4)<<1;
  266.     }
  267. }
  268.  
  269. static int testfor( int xp, int yp, int what )
  270. {
  271.     int f = 0;
  272.     int d1, d2;
  273.  
  274.     for( d1 = -1; d1 < 2; d1++ )
  275.         for( d2 = -1; d2 < 2; d2++ )
  276.             if( PF( xp + d1, yp + d2 ) == what )
  277.                 f++;
  278.     return( f );
  279. }
  280.  
  281. static void domiete( void )
  282. {
  283.     int c;
  284.  
  285.     printf( "<HR><H1>Die Miete ist fällig!</H1><HR>\n" );
  286.  
  287.     printf( "Es ist 'mal wieder so weit: Die Miete ist fällig, und wie üblich hat\n" );
  288.     printf( "einer der Zombies sein ganzes Geld verkifft.<P>\n" );
  289.  
  290.     if( tstate & 1 )
  291.     {
  292.         printf( "Leider ist der Mietkonto-Treuhänder auch verzombt und läßt sich\n" );
  293.         printf( "von den übrigen Zombies belabern, den Pleitezombie nicht vor die Tür zu\n" );
  294.         printf( "setzen.<P>\n" );
  295.         printf( "<H3><B>Du</B> musst für den Pleitezombie bezahlen...\</H3>\n" );
  296.  
  297.         if( !lives-- )
  298.         {
  299.             printf( "<HR><BR>Leider bist Du nun genau so pleite wie der Zombie,\n" );
  300.             printf( "womit das Spiel für Dich <I>gelaufen</I> ist.\n<P>" );
  301.             printf( "Tröste Dich, Du hast immerhin %d Züge lang gegen die Zombies\n", step );
  302.             printf( "durchgehalten.\n" );
  303.             return;
  304.         }
  305.  
  306.         printf( "<HR>Du hast jetzt nur noch %d weitere Chancen, bist Du auch Pleite bist...\n<P>", lives );
  307.  
  308.         printf( "<A HREF=\"/cgi-bin/zombie?" );
  309.         makeparmstring( 0, 0 );
  310.         printf( "\">[WEITER im Spiel]</A>" );
  311.         return;
  312.     }
  313.  
  314.     for( c = 0; c < 10; c++ )
  315.     {
  316.         if( pstate[ c ] & 1 )
  317.         {
  318.             pstate[ c ] &= ~1;
  319.             break;
  320.         }
  321.     }
  322.  
  323.     printf( "Mit vereinten Kräften wird er vor die Tür gesetzt und durch einen Lebenden ersetzt!\n<P>" );
  324.     printf( "<A HREF=\"/cgi-bin/zombie?" );
  325.     makeparmstring( 0, 0 );
  326.     printf( "\">[WEITER im Spiel]</A>" );
  327. }
  328.  
  329. static void dowin( void )
  330. {
  331.     printf( "<HR><H1>Gewonnen!</H1><HR>\n" );
  332.  
  333.     printf( "Du hast es in %d Schritten geschafft, die WG zombiefrei\n", step );
  334.     printf( "zu kriegen!\n" );
  335.     switch( RND( 3 ) )
  336.     {
  337.         case 0:
  338.             printf( "Der Oberzombie pfeift sich vor lauter\n" );
  339.             printf( "Frustration eine Überdosis Marusha rein und verbringt\n" );
  340.             printf( "den Rest seiner Tage in der Klapsmühle, wo er denkt,\n" );
  341.             printf( "er wäre ein Baum..." );
  342.             break;
  343.  
  344.         case 1:
  345.             printf( "Drei Tage später beobachtest Du den Oberzombie,\n" );
  346.             printf( "wie er die Katzen füttert. Offenbar wird auch er\n" );
  347.             printf( "langsam wieder normal.\n" );
  348.             break;
  349.  
  350.         case 2:
  351.             printf( "Der Oberzombie zieht in eine Sekten-Kommune um\n" );
  352.             printf( "und intoniert den ganzen Tag nur nach sein persönliches\n" );
  353.             printf( "Mantra, das ihm Außerirdische mitgeteilt haben." );
  354.             break;
  355.     }
  356.     printf( "<HR><H2>Gratulation!</H2>" );
  357.     return;
  358. }
  359.  
  360. static void dogame( char *arg )
  361. {
  362.     int c;
  363.     int zc = 0;
  364.  
  365.     parsearg( arg );
  366.  
  367.     nextmiete = 29 - ( step % 30 );
  368.  
  369.     if( !nextmiete )
  370.     {
  371.         domiete();
  372.         return;
  373.     }
  374.  
  375.     // Nun Player setzen
  376.     PF(my_x,my_y) = '@';
  377.     PF(oz_x,oz_y) = 'O';
  378.     PF(th_x,th_y) = ( tstate & 1 ) ? 't' : 'T';
  379.  
  380.     for( c = 0; c < 10; c++ )
  381.     {
  382.         PF( p_x[ c ], p_y[ c ] ) = ( pstate[ c ] & 1 ) ? 'Z' : 'L';
  383.     }
  384.  
  385.     // Player bewegen
  386.     for( c = 0; c < 10; c++ )
  387.     {
  388.         PF( p_x[ c ], p_y[ c ] ) = '.';
  389.         if( testfor( p_x[ c ], p_y[ c ], 'Z' ) )
  390.             pstate[ c ] |= 1;
  391.         if( testfor( p_x[ c ], p_y[ c ], 'L' ) > 1 )
  392.             pstate[ c ] &= ~1;
  393.         if( testfor( p_x[ c ], p_y[ c ], 'O' ) )
  394.             pstate[ c ] |= 1;
  395.         if( testfor( p_x[ c ], p_y[ c ], '@' ) )
  396.             pstate[ c ] &= ~1;
  397.         movep( &p_x[ c ], &p_y[ c ], &pstate[ c ] );
  398.         PF( p_x[ c ], p_y[ c ] ) = ( pstate[ c ] & 1 ) ? 'Z' : 'L';
  399.  
  400.         if( pstate[ c ] & 1 )
  401.             zc++;
  402.  
  403.     }
  404.     movep( &oz_x, &oz_y, &ostate );
  405.     if( testfor( th_x, th_y, 'O' ) || testfor( th_x, th_y, 'Z' ) )
  406.         tstate |= 1;
  407.     if( testfor( th_x, th_y, '@' ) )
  408.         tstate &= ~1;
  409.     movep( &th_x, &th_y, &tstate );
  410.  
  411.     memcpy( playfield, pf2, PFSIZE );
  412.  
  413.     if( !zc )
  414.     {
  415.         dowin();
  416.         return;
  417.     }
  418.  
  419.     printpf();
  420. }
  421.  
  422. int main( int argc, char **argv )
  423. {
  424.     srand( time( 0 ) );
  425.     memcpy( pf2, playfield, PFSIZE );
  426.  
  427.     printf( "Content-type: text/html\n\n" );
  428.     printf( "<TITLE>FIGHT THE ZOMBIES</TITLE><HEAD><H1>Fight The Zombies</H1></HEAD>\n<BODY>" );
  429.  
  430.     if( ( argc == 1 ) || ( strlen( argv[ 1 ] ) != 71 ) )
  431.         initgame();
  432.     else
  433.         dogame( argv[ 1 ] );
  434.  
  435.     printf( "<HR><I>Fight the Zombies</I> 1.0 nonsensed by <A HREF=\"http://www.pluribus.wupper.de/~owagner\">Oliver Wagner</A>" );
  436.     printf( "\n</BODY>\n" );
  437. }
  438.